package item.pickable;

import be.kuleuven.cs.som.annotate.*;
import attribute.*;

/**
 * @author John
 *
 */
public class Battery extends EnergyItem{
	private final static Energy MAX_ENERGY = new Energy(5000, EnergyUnit.Wattsecond);
	
	/**
	 * Initialises this new Battery with the given X and Y coordinate for the new position,
	 * 		the given energy, the given weight 
	 * 		and the given board it has to be placed on.
	 * 
	 * @param X
	 * 		The X coordinate of the battery's new position on the given board.
	 * @param Y
	 * 		The Y coordinate of the battery's new position on the given board.
	 * @param energy
	 * 		The amount of energy the battery must have.
	 * @param board
	 * 		The board the battery must be placed on.
	 * @param weight
	 * 		The weight the battery must have.
	 * 
	 * @pre	The given initial energy must be a valid energy for the battery
	 * 		|iisValidEnergy(energy, EnergyUnit.Wattsecond)sValidEnergy(energy)
	 * 
	 * @effect The new energy of the battery is set to the given energy using setEnergy().
	 * 			|new.getEnergy() = new Energy(energy, EnergyUnit.Wattsecond)
	 * 
	 * @effect The new weight of the battery is set to the given weight using setWeight().
	 * 			|This.setWeight(weight)
	 * 
	 * @effect The position and board of the battery is set using setValidPosition(X, Y, board)
	 * 			| this.setValidPosition(X, Y, board)
	 */
	public Battery(long X, long Y, double energy, int weight, Board board){
		assert this.canHaveAsEnergy(energy, EnergyUnit.Wattsecond);
		this.setEnergy(new Energy(energy, EnergyUnit.Wattsecond));
		this.setWeight(weight);
		this.setValidPosition(X, Y, board);
		}
	
	/**
	 * Initialise a new Battery with given energy and weight.
	 * 
	 * @param energy
	 * 			The energy the battery must have.
	 * @param weight
	 * 			The weight the battery must have.
	 * 
	 * @pre		...
	 * 			|isValidEnergy(energy, EnergyUnit.Wattsecond)
	 * 
	 * @effect	...
	 * 			|new.getEnergy() = new Energy(energy, EnergyUnit.Wattsecond);
	 * 
	 * @effect	...
	 * 			|this.setWeight(weight)
	 */
	public Battery(double energy, int weight){
		assert(this.canHaveAsEnergy(energy, EnergyUnit.Wattsecond));
		this.setEnergy(new Energy(energy, EnergyUnit.Wattsecond));
		this.setWeight(weight);
	}

	/**
	 * Returns the Max energy of this class
	 */
	@Basic @Immutable
	public static Energy getMaxEnergy(){
		return MAX_ENERGY;
	}
	
	/**
	 * 
	 * Checks whether the given initial energy is valid
	 * 
	 * @param energyDouble
	 * 			The energyDouble to check.
	 * @param unit 
	 * 			The energy unit to check.
	 * 
	 * @return	Returns true if and only if the given energy is bigger than or equal to the minimum energy 
	 * 				and smaller than or equal to the maximum energy.
	 * 			|result == (new Energy(energyDouble, unit).compareTo(getMinEnergy()) >= 0 
	 *			|	&& new Energy(energyDouble, unit).compareTo(getMaxEnergy()) <= 0)
	 */
	@Override @Model
	public boolean canHaveAsEnergy(double energyDouble, EnergyUnit unit){
		return (new Energy(energyDouble, unit).compareTo(getMinEnergy()) >= 0 
				&& new Energy(energyDouble, unit).compareTo(getMaxEnergy()) <= 0);
	}
	
	
	@Override
	public boolean hasAtleast(Object condition){
		if(condition.getClass() == int.class){
			if(this.getWeight() >= (Integer)condition)
				return true;
		}
		else if(condition.getClass() == Energy.class){
			if((this.getEnergy().compareTo((Energy)condition)) >= 0)
					return true;
		}
		else if(condition.getClass() == Position.class){
			if((this.getPosition() == ((Position)condition)))
				return true;
		}
		return false;
	}
}